home *** CD-ROM | disk | FTP | other *** search
- {
- > Another problem is plotting sprites with "invisible" pixels. In other
- > words, all pixels in the sprite are plotted except for ones with a color
- > of 255 (I think I've heard that Origin used this method in Ultima 6).
- > Because of my unsuccessful try with asm earlier, I didn't even bother to
- > try this in asm. Unfortunately, the following is MUCH too slow:
-
- try this!
- }
- uses crt;
- type SpriteType = array[0..15,0..15] of byte;
-
- var sprite : spritetype;
- f : file of spritetype; {sprite's image is stored in file}
- x, y : word;
-
- procedure putinvspriteinasm(x, y : word; sprite : spritetype);
- var p : pointer;
- segm, offs : word;
- {these are used to calculate destination address
- in video memory}
-
- begin
- p := addr(sprite[0,0]);
- {this pointer is used only to cheat tp. tp doesn't allow to use addr or
- @ operators in inline asm - or i don't know how to do it}
- segm := $a000 + (320 * y) div 16;
- offs := x;
- {segm:offs is address of upper left corner of sprite in video RAM}
- asm
- push ds
- {ds is one of the important registers in tp and must be saved}
- lds si, p
- {ds:si now is source address for sprite's array}
- mov es, segm
- mov di, offs
- {es:di now is target address in VRAM}
- mov bh, 16
- {counter for outer loop}
- @loop2: mov bl, 16
- @loop1: mov al, [ds:si]
- {innner loop (marked with label @loop1) is used to draw each line of
- sprite}
- cmp al, $ff
- {make sure if pixel is $ff or not}
- je @skip
- {it is - so we don't draw it}
- mov [es:di], al
- {no, it's not - draw!}
- @skip: inc si
- inc di
- dec bl
- jnz @loop1
- {we haven't finished to draw this line if bl > 0}
- dec bh
- {we haven't finished to draw all image if bh > 0}
- jz @end
- add di, 320 - 16
- {calculate beginning of next line}
- jmp @loop2
- @end:
- pop ds
-
- end
- end;
-
- begin
- asm mov ax, 0013h
- int 10h
- end;
- assign(f, 'sprite');
- reset(f);
- read(f, sprite);
- close(f);
- randomize;
- repeat
- x := random(320);
- y := random(200);
- putinvspriteinasm(x, y, sprite);
- until keypressed;
- end.
- {
- i added into code some quick'n'dirty comments to let you understand
- how assembly works. i've tested this code and found that it won't work with
- Microsoft's workgrp.sys driver - the programm simply crashes when you press a
- key. (workgrp.sys driver is one of the Windows for Workgroups drivers).
- strange... with all other things (qemm386, lan drivers etc.) programm seems to
- work fine. one more thing i must add that better is to pass to procedure
- putsprite not array with sprite's data but only pointer to it - because tp
- moves all this data around memory - and in this case it's 256 bytes.
- }